package craky.componentc;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;

import javax.swing.Icon;
import javax.swing.border.EmptyBorder;

import craky.component.JImagePane;
import craky.layout.LinearLayout;
import craky.util.UIResourceManager;

public class JCMessageBox extends JCDialog implements ActionListener
{
    private static final long serialVersionUID = 3983953036367048891L;
    
    public static final int CLOSE_OPTION = 0;
    
    public static final int OK_OPTION = 1;
    
    public static final int CANCEL_OPTION = 1 << 1;
    
    public static final int YES_OPTION = 1 << 2;
    
    public static final int NO_OPTION = 1 << 3;

    public static enum MessageType
    {
        ERROR, INFORMATION, WARNING, QUESTION
    }
    
    private JCButton btnOK, btnCancel, btnYes, btnNo;
    
    private JCLabel lbMessage;
    
    private Map<MessageType, Icon> iconMap;
    
    private int option;
    
    private JCMessageBox(Window owner, String title, String message, MessageType messageType, int option)
    {
        super(owner, title, ModalityType.DOCUMENT_MODAL);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        init(message, messageType, option);
    }
    
    public static JCMessageBox createMessageBox(Window parent, String title, String message, MessageType messageType, int option)
    {
        return new JCMessageBox(parent, title, message, messageType, option);
    }
    
    public static JCMessageBox createErrorMessageBox(Window parent, String title, String message)
    {
        return createErrorMessageBox(parent, title, message, OK_OPTION);
    }
    
    public static JCMessageBox createErrorMessageBox(Window parent, String title, String message, int option)
    {
        return createMessageBox(parent, title, message, MessageType.ERROR, option);
    }
    
    public static JCMessageBox createInformationMessageBox(Window parent, String title, String message)
    {
        return createInformationMessageBox(parent, title, message, OK_OPTION);
    }
    
    public static JCMessageBox createInformationMessageBox(Window parent, String title, String message, int option)
    {
        return createMessageBox(parent, title, message, MessageType.INFORMATION, option);
    }
    
    public static JCMessageBox createWarningMessageBox(Window parent, String title, String message)
    {
        return createWarningMessageBox(parent, title, message, OK_OPTION | CANCEL_OPTION);
    }
    
    public static JCMessageBox createWarningMessageBox(Window parent, String title, String message, int option)
    {
        return createMessageBox(parent, title, message, MessageType.WARNING, option);
    }
    
    public static JCMessageBox createQuestionMessageBox(Window parent, String title, String message)
    {
        return createQuestionMessageBox(parent, title, message, YES_OPTION | NO_OPTION);
    }
    
    public static JCMessageBox createQuestionMessageBox(Window parent, String title, String message, int option)
    {
        return createMessageBox(parent, title, message, MessageType.QUESTION, option);
    }
    
    private void init(String message, MessageType messageType, int option)
    {
        iconMap = new HashMap<MessageType, Icon>();
        iconMap.put(MessageType.ERROR, UIResourceManager.getIcon(UIResourceManager.KEY_MESSAGE_BOX_ERROR_ICON));
        iconMap.put(MessageType.INFORMATION, UIResourceManager.getIcon(UIResourceManager.KEY_MESSAGE_BOX_INFORMATION_ICON));
        iconMap.put(MessageType.QUESTION, UIResourceManager.getIcon(UIResourceManager.KEY_MESSAGE_BOX_QUESTION_ICON));
        iconMap.put(MessageType.WARNING, UIResourceManager.getIcon(UIResourceManager.KEY_MESSAGE_BOX_WARNING_ICON));
        
        JImagePane buttonPane = new JImagePane();
        lbMessage = new JCLabel(message, iconMap.get(messageType), JCLabel.LEFT);
        btnOK = new JCButton("\u786E\u5B9A");
        btnCancel = new JCButton("\u53D6\u6D88");
        btnYes = new JCButton("\u662F");
        btnNo = new JCButton("\u5426");
        JCButton[] buttons = {btnOK, btnYes, btnNo, btnCancel};
        int[] options = {OK_OPTION, YES_OPTION, NO_OPTION, CANCEL_OPTION};
        final Dimension buttonSize = new Dimension(69, 21);
        int index = 0;
        boolean hasDefaultButton = false;
        
        lbMessage.setBackground(UIResourceManager.getWhiteColor());
        lbMessage.setBackgroundAlpha(0.9f);
        lbMessage.setIconTextGap(16);
        lbMessage.setHorizontalAlignment(JCLabel.LEFT);
        lbMessage.setVerticalAlignment(JCLabel.TOP);
        lbMessage.setVerticalTextPosition(JCLabel.TOP);
        lbMessage.setBorder(new EmptyBorder(15, 25, 15, 25));
        lbMessage.setDeltaY(5);
        buttonPane.setLayout(new LinearLayout(6, 0, 0, 0, 0, LinearLayout.LEADING, LinearLayout.LEADING, LinearLayout.HORIZONTAL));
        buttonPane.setPreferredSize(new Dimension(-1, 33));
        buttonPane.setBorder(new EmptyBorder(5, 9, 0, 9));
        buttonPane.setBackground(new Color(255, 255, 255, 170));
        buttonPane.setCornerSizeAt(3, 2);
        buttonPane.setCornerSizeAt(4, 2);
        
        for(JCButton button: buttons)
        {
            button.setActionCommand(String.valueOf(options[index]));
            button.setPreferredSize(buttonSize);
            button.setVisible((option & options[index]) != 0);
            button.addActionListener(this);
            buttonPane.add(button, LinearLayout.END);
            index++;
            
            if(!hasDefaultButton && button.isVisible())
            {
                getRootPane().setDefaultButton(button);
                hasDefaultButton = true;
            }
        }
        
        getContentPane().setLayout(new LinearLayout(0, 1, 1, 3, 1, LinearLayout.LEADING, LinearLayout.LEADING, LinearLayout.VERTICAL));
        getContentPane().add(lbMessage, LinearLayout.MIDDLE_FILL);
        getContentPane().add(buttonPane, LinearLayout.END_FILL);
    }
    
    public int open()
    {
        option = CLOSE_OPTION;
        this.setSize(this.getPreferredSize());
        this.setLocationRelativeTo(this.getParent());
        this.setResizable(false);
        this.setVisible(true);
        return option;
    }
    
    public Dimension getPreferredSize()
    {
        int width = Math.max(315, lbMessage.getPreferredSize().width) + 15;
        int height = Math.max(150, lbMessage.getPreferredSize().height + 15 + 28 + 34);
        return new Dimension(width, height);
    }
    
    public void actionPerformed(ActionEvent e)
    {
        JCButton button = (JCButton)e.getSource();
        option = Integer.parseInt(button.getActionCommand());
        this.dispose();
    }
}